package com.buba.springcloud.util;

import com.buba.springcloud.entities.HfStaff;
import com.buba.springcloud.entities.HfUser;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

public class JwtUtil {


    //签名秘钥: 这个秘钥不能外露
    public final static String secret = "adfa343affa34";
    /**
     * 用户登录成功后生成Jwt
     * 使用Hs256算法  私匙使用用户密码
     * @param ttlMillis jwt过期时间
     * @param user      登录成功的user对象
     * @return
     */
    public static String createJWT(long ttlMillis, HfUser user) {
        //指定签名的时候使用的签名算法
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;

        //生成JWT的时间
        long nowMillis = System.currentTimeMillis();
        Date now = new Date(nowMillis);

        //创建payload的私有声明

        Map<String, Object> claims = new HashMap<String, Object>();
        claims.put("id",user.getId());
        claims.put("username", user.getEmail());
        //生成签发人 (这个token是给谁的)
        String subject = user.getEmail();

        //下面就是在为payload添加各种标准声明和私有声明了
        //这里其实就是new一个JwtBuilder，设置jwt的body
        JwtBuilder builder;
        builder = Jwts.builder()
                //如果有私有声明，一定要先设置这个自己创建的私有的声明，这个是给builder的claim赋值，一旦写在标准的声明赋值之后，就是覆盖了那些标准的声明的
                .setClaims(claims)
                //设置唯一id
                .setId(UUID.randomUUID().toString())
                //iat: jwt的签发时间
                .setIssuedAt(now)
                //代表这个JWT的主体(是谁)
                .setSubject(subject)
                //设置签名使用的签名算法和签名使用的秘钥
                .signWith(signatureAlgorithm, secret);
        if (ttlMillis >= 0) {
            long expMillis = nowMillis + ttlMillis;
            Date exp = new Date(expMillis);
            //设置过期时间
            builder.setExpiration(exp);
        }
        return builder.compact();
    }


    public static String createJWT(long ttlMillis, HfStaff staff) {
        //指定签名的时候使用的签名算法
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;

        //生成JWT的时间
        long nowMillis = System.currentTimeMillis();
        Date now = new Date(nowMillis);

        //创建payload的私有声明

        Map<String, Object> claims = new HashMap<String, Object>();
        claims.put("id",staff.getId());
        //生成签发人 (这个token是给谁的)
        String subject = staff.getEmail();

        //下面就是在为payload添加各种标准声明和私有声明了
        //这里其实就是new一个JwtBuilder，设置jwt的body
        JwtBuilder builder;
        builder = Jwts.builder()
                //如果有私有声明，一定要先设置这个自己创建的私有的声明，这个是给builder的claim赋值，一旦写在标准的声明赋值之后，就是覆盖了那些标准的声明的
                .setClaims(claims)
                //设置唯一id
                .setId(UUID.randomUUID().toString())
                //iat: jwt的签发时间
                .setIssuedAt(now)
                //代表这个JWT的主体(是谁)
                .setSubject(subject)
                //设置签名使用的签名算法和签名使用的秘钥
                .signWith(signatureAlgorithm, secret);
        if (ttlMillis >= 0) {
            long expMillis = nowMillis + ttlMillis;
            Date exp = new Date(expMillis);
            //设置过期时间
            builder.setExpiration(exp);
        }
        return builder.compact();
    }

    /**
     * Token的解密
     * @param token 加密后的token
     * @return
     */
    public static Claims parseJWT(String token) {

        //得到DefaultJwtParser
        Claims claims = Jwts.parser()
                //设置签名的秘钥
                .setSigningKey(secret)
                //设置需要解析的jwt
                .parseClaimsJws(token).getBody();

        return claims;
    }


    public static void main(String[] args) throws UnsupportedEncodingException {
        HfUser lu = new HfUser();
        lu.setId(1000);
        lu.setEmail("abc");


        String jwt = createJWT(1000 * 200, lu);

        System.out.println(jwt);



//        String jwt = "eyJhbGciOiJIUzI1NiJ9.eeyJzdWIiOiJhYmMiLCJpZCI6MTAwMCwiZXhwIjoxNjMyMTk1OTg5LCJpYXQiOjE2MzIxOTU3ODksImp0aSI6IjZlZDFlNjIwLWUyMmQtNGJiYi04ZDU4LTE0YmUxZDJkMTA0MCIsInVzZXJuYW1lIjoiYWJjIn0.Wd9rZA8SdztrhM6JMYllUmYlbSheivThYPWHkllSqtQ";
        Claims claims = parseJWT(jwt);
        System.out.println(claims.toString());





    }
}
